package com.example.demo.proxy.impl;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.example.demo.model.dto.*;
import com.example.demo.model.req.*;
import com.example.demo.proxy.AvataProxy;
import com.example.demo.util.AvataProperties;
import com.example.demo.util.AvataUtils;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;

import javax.annotation.Resource;
import java.net.URI;
import java.util.HashMap;
import java.util.Map;


@Slf4j
@Service
@AllArgsConstructor
public class AvataProxyImpl implements AvataProxy {

    @Autowired
    private AvataProperties avataProperties;
    @Resource
    private RestTemplate restTemplate;

    private static final String CREATE_ACCOUNT_URL = "/v1beta1/account";

    private static final String CREATE_ACCOUNT_URL_LIST = "/v1beta1/accounts";

    private static  final String ACCOUNT_LIST_QUERY ="/v1beta1/accounts";

    private static final String NFT_CLASS_LIST_QUERY_LIST = "/v1beta1/nft/classes";

    private static final String NFT_PUBLISH_URL_PRE = "/v1beta1/nft/nfts/";

    private static final String NFT_QUERY_URL= "/v1beta1/nft/nfts/";

    private  static final String NFT_PUBLISH_LIST = "/v1beta1/nft/batch/nfts/";

    private static final String DEAL_RESULT_QUERY_URL_PRE = "/v1beta1/tx/";

    private static final String NFT_TRANSFER_URL_PRE = "/v1beta1/nft/nft-transfers/";

    private static final String NFT_CREATE_URL = "/v1beta1/nft/classes";


    /*
    创建链账户
     */
    @Override
    public CreateAccountDTO createAccount(String name, String operationId) {
        if (StringUtils.isBlank(name)) {
            throw new RuntimeException("缺少必传参数name");
        }
        if (StringUtils.isBlank(operationId)) {
            throw new RuntimeException("缺少必传参数operationId");
        }
        Long currentTime  = System.currentTimeMillis();
        // 请求body
        Map<String, Object> body = new HashMap<>();
        body.put("name", name);
        body.put("operation_id", operationId);
        // 验签
        String signature = AvataUtils.signRequest(CREATE_ACCOUNT_URL, null, body, currentTime, avataProperties.getApiSecret());
        // 请求体
        HttpHeaders headers = getHttpHeader(signature, currentTime);
        headers.setContentType(MediaType.parseMediaType("application/json"));

        HttpEntity<String> httpEntity = new HttpEntity<>(JSONObject.toJSONString(body), headers);

        String url = avataProperties.getAvataUrl() + CREATE_ACCOUNT_URL;
        log.info("文昌链接口请求地址"+url);
        try {
            // 接口调用
            ParameterizedTypeReference<Message<CreateAccountDTO>> typeReference = new ParameterizedTypeReference<Message<CreateAccountDTO>>() {
            };
            ResponseEntity<Message<CreateAccountDTO>> responseEntity;
            responseEntity = restTemplate.exchange(url, HttpMethod.POST, httpEntity, typeReference);

            Message<CreateAccountDTO> message = responseEntity.getBody();

            CreateAccountDTO createAccountDTO = message.getData();
            // 成功
            log.info("创建链账户成功:" + createAccountDTO);

            return createAccountDTO;
        } catch (Exception e) {
            // 非200都会抛异常
            // 处理异常
            log.info("非200处理链账户创建失败:"+name+":"+operationId);
            e.printStackTrace();
            throw new RuntimeException("链账户创建失败");
        }
    }

    @Override
    public CreateAccountListDTO createAccountList(Integer count, String operation_id) {
        if (StringUtils.isBlank(operation_id)) {
            throw new RuntimeException("缺少必传参数operationId");
        }
        Long currentTime  = System.currentTimeMillis();
        // 请求body
        Map<String, Object> body = new HashMap<>();
        body.put("count", count);
        body.put("operation_id", operation_id);
        // 验签
        String signature = AvataUtils.signRequest(CREATE_ACCOUNT_URL_LIST, null, body, currentTime, avataProperties.getApiSecret());
        // 请求体
        HttpHeaders headers = getHttpHeader(signature, currentTime);
        headers.setContentType(MediaType.parseMediaType("application/json"));

        HttpEntity<String> httpEntity = new HttpEntity<>(JSONObject.toJSONString(body), headers);

        String url = avataProperties.getAvataUrl() + CREATE_ACCOUNT_URL_LIST;
        log.info("文昌链接口请求地址"+url);
        try {
            // 接口调用
            ParameterizedTypeReference<Message<CreateAccountListDTO>> typeReference = new ParameterizedTypeReference<Message<CreateAccountListDTO>>() {
            };
            ResponseEntity<Message<CreateAccountListDTO>> responseEntity;
            responseEntity = restTemplate.exchange(url, HttpMethod.POST, httpEntity, typeReference);

            Message<CreateAccountListDTO> message = responseEntity.getBody();

            CreateAccountListDTO createAccountListDTO = message.getData();
            // 成功
            log.info("批量创建链账户成功:" + createAccountListDTO);

            return createAccountListDTO;
        } catch (Exception e) {
            // 非200都会抛异常
            // 处理异常
            log.info("非200处理链账户创建失败");
            e.printStackTrace();
            throw new RuntimeException("链账户创建失败");
        }
    }

    @Override
    public NFTClassListDTO queryNFTClassList(NFTClassListReq nftClassListReq) {
        Map<String, Object> query = null == nftClassListReq ? new HashMap<>() :
                JSON.parseObject(JSON.toJSONString(nftClassListReq), new TypeReference<Map<String, Object>>() {
                });
        Long currentTime = System.currentTimeMillis();
        // 验签
        String signature = AvataUtils.signRequest(NFT_CLASS_LIST_QUERY_LIST, query, null, currentTime, avataProperties.getApiSecret());

        UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(avataProperties.getAvataUrl() + NFT_CLASS_LIST_QUERY_LIST);
        for (Map.Entry<String, Object> entry : query.entrySet()) {
            builder.queryParam(entry.getKey(), entry.getValue());
        }

        HttpHeaders headers = getHttpHeader(signature, currentTime);

        try {
            // 接口调用
            ParameterizedTypeReference<Message<NFTClassListDTO>> typeReference = new ParameterizedTypeReference<Message<NFTClassListDTO>>() {
            };
            ResponseEntity<Message<NFTClassListDTO>> responseEntity = restTemplate.exchange(new URI(builder.toUriString()), HttpMethod.GET, new HttpEntity<>(headers), typeReference);

            Message<NFTClassListDTO> message = responseEntity.getBody();
            NFTClassListDTO nftClassListDTO = message.getData();

            if (null != nftClassListDTO && null != nftClassListDTO.getClasses() && nftClassListDTO.getClasses().size() != 0) {
                // 遍历处理类别列表
                for (NFTClassDTO nftClassDTO : nftClassListDTO.getClasses()) {

                }
            }

            log.info("NFT类别查询结果：" + nftClassListDTO);

            return nftClassListDTO;

        } catch (Exception e) {
            // 非200都会抛异常
            // 处理异常
            log.info("非200查询NFT类别失败:"+nftClassListReq);
            e.printStackTrace();
            throw new RuntimeException("查询NFT类别失败");
        }
    }

    @Override
    public NFTListDTO queryNFTList(NFTReq nftReq) {
        Map<String, Object> query = null == nftReq? new HashMap<>() : JSON.parseObject(JSON.toJSONString(nftReq), new TypeReference<Map<String, Object>>() {});
        Long currentTime = System.currentTimeMillis();
        // 验签
        String signature = AvataUtils.signRequest(NFT_QUERY_URL, query, null, currentTime, avataProperties.getApiSecret());

        UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(avataProperties.getAvataUrl() + NFT_QUERY_URL);
        for (Map.Entry<String, Object> entry : query.entrySet()) {
            builder.queryParam(entry.getKey(), entry.getValue());
        }

        HttpHeaders headers = getHttpHeader(signature, currentTime);

        try {
            // 接口调用
            ParameterizedTypeReference<Message<NFTListDTO>> typeReference = new ParameterizedTypeReference<Message<NFTListDTO>>() {
            };
            ResponseEntity<Message<NFTListDTO>> responseEntity = restTemplate.exchange(new URI(builder.toUriString()), HttpMethod.GET, new HttpEntity<>(headers), typeReference);

            Message<NFTListDTO> message = responseEntity.getBody();
            NFTListDTO nftListDTO = message.getData();

            if (null != nftListDTO && null != nftListDTO.getNfts() && nftListDTO.getNfts().size() != 0) {
                // 遍历处理类别列表
                for (NFT nft :nftListDTO.getNfts()) {
                }
            }

            log.info("NFT类别查询结果：" + nftListDTO);

            return nftListDTO;

        } catch (Exception e) {
            // 非200都会抛异常
            // 处理异常
            log.info("非200查询NFT失败:"+nftReq);
            e.printStackTrace();
            throw new RuntimeException("查询NFT失败");
        }
    }

    @Override
    public NFTOperateDTO publishNFT(NFTPublishReq nftPublishReq) {
        if (null == nftPublishReq) {
            log.info("发行NFT失败，缺少参数:"+ null);
            throw new RuntimeException("发行NFT失败，缺少参数");
        }
        if (null == nftPublishReq.getClass_id()) {
            log.info("发行NFT失败，缺少参数class_id:"+nftPublishReq);
            throw new RuntimeException("发行NFT失败，缺少参数class_id");
        }
        if (null == nftPublishReq.getName()) {
            log.info("发行NFT失败，缺少参数name:"+nftPublishReq);
            throw new RuntimeException("发行NFT失败，缺少参数name");
        }
        if (null == nftPublishReq.getOperation_id()) {
            log.info("发行NFT失败，缺少参数operation_id:"+nftPublishReq);
//            throw new RuntimeException("发行NFT失败，缺少参数operation_id");
        }

        String path = NFT_PUBLISH_URL_PRE + nftPublishReq.getClass_id();

        Map<String, Object> body = JSON.parseObject(JSON.toJSONString(nftPublishReq), new TypeReference<Map<String, Object>>() {
        });

        body.remove("class_id");

        Long currentTime = System.currentTimeMillis();
        // 验签
        String signature = AvataUtils.signRequest(path, null, body, currentTime, avataProperties.getApiSecret());
        // 请求体
        HttpHeaders headers = getHttpHeader(signature, currentTime);
        headers.setContentType(MediaType.parseMediaType("application/json"));

        HttpEntity<String> httpEntity = new HttpEntity<>(JSONObject.toJSONString(body), headers);

        String url = avataProperties.getAvataUrl() + path;
        try {
            // 接口调用
            ParameterizedTypeReference<Message<NFTOperateDTO>> typeReference = new ParameterizedTypeReference<Message<NFTOperateDTO>>() {
            };
            ResponseEntity<Message<NFTOperateDTO>> responseEntity = restTemplate.exchange(url, HttpMethod.POST, httpEntity, typeReference);

            Message<NFTOperateDTO> message = responseEntity.getBody();

            NFTOperateDTO nftOperateDTO = message.getData();
            // 成功
            log.info("发行NFT成功:" + nftOperateDTO);

            return nftOperateDTO;
        } catch (Exception e) {
            // 非200都会抛异常
            // 处理异常
            log.info("非200发行NFT失败:参数为："+nftPublishReq);
            e.printStackTrace();
            throw new RuntimeException("发行NFT失败");
        }
    }

    @Override
    public NFTPublishListDTO publisNFTList(NFTPublishListReq nftPublishListReq) {
        if (null == nftPublishListReq) {
            log.info("发行NFT失败，缺少参数:"+ null);
            throw new RuntimeException("发行NFT失败，缺少参数");
        }
        if (null == nftPublishListReq.getClass_id()) {
            log.info("发行NFT失败，缺少参数class_id:"+nftPublishListReq);
            throw new RuntimeException("发行NFT失败，缺少参数class_id");
        }
        if (null ==nftPublishListReq.getName()) {
            log.info("发行NFT失败，缺少参数name:"+nftPublishListReq);
            throw new RuntimeException("发行NFT失败，缺少参数name");
        }
        if (null == nftPublishListReq.getOperation_id()) {
            log.info("发行NFT失败，缺少参数operation_id:"+nftPublishListReq);
//            throw new RuntimeException("发行NFT失败，缺少参数operation_id");
        }

        String path = NFT_PUBLISH_LIST + nftPublishListReq.getClass_id();

        Map<String, Object> body = JSON.parseObject(JSON.toJSONString(nftPublishListReq), new TypeReference<Map<String, Object>>() {
        });

        body.remove("class_id");

        Long currentTime = System.currentTimeMillis();
        // 验签
        String signature = AvataUtils.signRequest(path, null, body, currentTime, avataProperties.getApiSecret());
        // 请求体
        HttpHeaders headers = getHttpHeader(signature, currentTime);
        headers.setContentType(MediaType.parseMediaType("application/json"));

        HttpEntity<String> httpEntity = new HttpEntity<>(JSONObject.toJSONString(body), headers);

        String url = avataProperties.getAvataUrl() + path;
        try {
            // 接口调用
            ParameterizedTypeReference<Message<NFTPublishListDTO>> typeReference = new ParameterizedTypeReference<Message<NFTPublishListDTO>>() {
            };
            ResponseEntity<Message<NFTPublishListDTO>> responseEntity = restTemplate.exchange(url, HttpMethod.POST, httpEntity, typeReference);

            Message<NFTPublishListDTO> message = responseEntity.getBody();

            NFTPublishListDTO nftPublishListDTO = message.getData();
            // 成功
            log.info("发行NFT成功:" + nftPublishListDTO);

            return nftPublishListDTO;
        } catch (Exception e) {
            // 非200都会抛异常
            // 处理异常
            log.info("非200发行NFT失败:参数为："+nftPublishListReq);
            e.printStackTrace();
            throw new RuntimeException("发行NFT失败");
        }
    }

    @Override
    public DealResultDTO queryDealResult(String taskId) {
        if (StringUtils.isBlank(taskId)) {
            log.info("上链交易结果查询失败，缺少参数taskId:"+taskId);
            throw new RuntimeException("上链交易结果查询失败，缺少参数taskId");
        }

        String path = DEAL_RESULT_QUERY_URL_PRE + taskId;

        Long currentTime = System.currentTimeMillis();
        // 验签
        String signature = AvataUtils.signRequest(path, null, null, currentTime, avataProperties.getApiSecret());

        HttpHeaders headers = getHttpHeader(signature, currentTime);

        try {
            // 接口调用
            ParameterizedTypeReference<Message<DealResultDTO>> typeReference = new ParameterizedTypeReference<Message<DealResultDTO>>() {
            };
            ResponseEntity<Message<DealResultDTO>> responseEntity = restTemplate.exchange(avataProperties.getAvataUrl() + path, HttpMethod.GET, new HttpEntity<>(headers), typeReference);

            Message<DealResultDTO> message = responseEntity.getBody();
            DealResultDTO dealResultDTO = message.getData();
            log.info("上链交易结果查询：" + dealResultDTO);
            return dealResultDTO;

        } catch (Exception e) {
            // 非200都会抛异常
            // 处理异常
            log.info("非200上链交易结果查询失败");
            e.printStackTrace();
            throw new RuntimeException("上链交易结果查询失败");
        }
    }

    @Override
    public NFTDetailDTO queryDetail(String class_id, String nft_id) {
        if (StringUtils.isBlank(class_id)) {
            log.info("查询失败，缺少参数class_id:"+class_id);
            throw new RuntimeException("上链交易结果查询失败，缺少参数class_id");
        }
        if (StringUtils.isBlank(nft_id)) {
            log.info("果查询失败，缺少参数nft_id:"+nft_id);
            throw new RuntimeException("上链交易结果查询失败，缺少参数nft_id");
        }

        String path = NFT_QUERY_URL + class_id + "/" +nft_id;

        Long currentTime = System.currentTimeMillis();
        // 验签
        String signature = AvataUtils.signRequest(path, null, null, currentTime, avataProperties.getApiSecret());

        HttpHeaders headers = getHttpHeader(signature, currentTime);

        try {
            // 接口调用
            ParameterizedTypeReference<Message<NFTDetailDTO>> typeReference = new ParameterizedTypeReference<Message<NFTDetailDTO>>() {
            };
            ResponseEntity<Message<NFTDetailDTO>> responseEntity = restTemplate.exchange(avataProperties.getAvataUrl() + path, HttpMethod.GET, new HttpEntity<>(headers), typeReference);

            Message<NFTDetailDTO> message = responseEntity.getBody();
            NFTDetailDTO nftDetailDTO = message.getData();
            log.info("结果查询：" + nftDetailDTO);
            return nftDetailDTO;

        } catch (Exception e) {
            // 非200都会抛异常
            // 处理异常
            log.info("非200nft详情查询失败");
            e.printStackTrace();
            throw new RuntimeException("nft详情查询失败");
        }
    }

    @Override
    public NFTOperateDTO transferNFT(NFTTransferReq nftTransferReq) {
        if (null == nftTransferReq) {
            log.info("转让NFT失败，缺少参数:"+nftTransferReq);
            throw new RuntimeException("转让NFT失败，缺少参数");
        }
        if (null == nftTransferReq.getClass_id()) {
            log.info("转让NFT失败，缺少参数class_id:"+nftTransferReq);
            throw new RuntimeException("转让NFT失败，缺少参数class_id");
        }
        if (null == nftTransferReq.getOwner()) {
            log.info("转让NFT失败，缺少参数owner:"+nftTransferReq);
            throw new RuntimeException("转让NFT失败，缺少参数owner");
        }
        if (null == nftTransferReq.getNft_id()) {
            log.info("转让NFT失败，缺少参数nft_id:"+nftTransferReq);
            throw new RuntimeException("转让NFT失败，缺少参数nft_id");
        }
        if (null == nftTransferReq.getRecipient()) {
            log.info("转让NFT失败，缺少参数recipient:"+nftTransferReq);
            throw new RuntimeException("转让NFT失败，缺少参数recipient");
        }
        if (null == nftTransferReq.getOperation_id()) {
            log.info("转让NFT失败，缺少参数operation_id:"+nftTransferReq);
            throw new RuntimeException("转让NFT失败，缺少参数operation_id");
        }

        String path = NFT_TRANSFER_URL_PRE + nftTransferReq.getClass_id() + "/" + nftTransferReq.getOwner() + "/" + nftTransferReq.getNft_id();

        Map<String, Object> body = JSON.parseObject(JSON.toJSONString(nftTransferReq), new TypeReference<Map<String, Object>>() {
        });

        body.remove("class_id");
        body.remove("owner");
        body.remove("nft_id");

        Long currentTime = System.currentTimeMillis();
        // 验签
        String signature = AvataUtils.signRequest(path, null, body, currentTime, avataProperties.getApiSecret());
        // 请求体
        HttpHeaders headers = getHttpHeader(signature, currentTime);
        headers.setContentType(MediaType.parseMediaType("application/json"));

        HttpEntity<String> httpEntity = new HttpEntity<>(JSONObject.toJSONString(body), headers);

        String url = avataProperties.getAvataUrl() + path;
        try {
            // 接口调用
            ParameterizedTypeReference<Message<NFTOperateDTO>> typeReference = new ParameterizedTypeReference<Message<NFTOperateDTO>>() {
            };
            ResponseEntity<Message<NFTOperateDTO>> responseEntity = restTemplate.exchange(url, HttpMethod.POST, httpEntity, typeReference);

            Message<NFTOperateDTO> message = responseEntity.getBody();

            NFTOperateDTO nftOperateDTO = message.getData();
            // 成功
            log.info("转让NFT成功:" + nftOperateDTO);

            return nftOperateDTO;
        } catch (Exception e) {
            // 非200都会抛异常
            // 处理异常
            log.info("转让NFT失败"+nftTransferReq);
            e.printStackTrace();
            throw new RuntimeException("转让NFT失败");
        }
    }

    @Override
    public NFTOperateDTO createNFT(NFTCreateReq nftCreateReq) {
        if (null == nftCreateReq) {
            log.info("创建NFT失败，缺少参数："+ null);
            throw new RuntimeException("创建NFT失败，缺少参数");
        }
        if (null == nftCreateReq.getName()) {
            log.info("创建NFT失败，缺少参数name："+nftCreateReq);
            throw new RuntimeException("创建NFT失败，缺少参数name");
        }
        if (null == nftCreateReq.getOwner()) {
            log.info("创建NFT失败，缺少参数owner："+nftCreateReq);
            throw new RuntimeException("创建NFT失败，缺少参数owner");
        }
        if (null == nftCreateReq.getOperation_id()) {
            log.info("创建NFT失败，缺少参数operation_id："+nftCreateReq);
            throw new RuntimeException("创建NFT失败，缺少参数operation_id");
        }

        Map<String, Object> body = JSON.parseObject(JSON.toJSONString(nftCreateReq), new TypeReference<Map<String, Object>>() {
        });


        Long currentTime = System.currentTimeMillis();
        // 验签
        String signature = AvataUtils.signRequest(NFT_CREATE_URL, null, body, currentTime, avataProperties.getApiSecret());
        // 请求体
        HttpHeaders headers = getHttpHeader(signature, currentTime);
        headers.setContentType(MediaType.parseMediaType("application/json"));

        HttpEntity<String> httpEntity = new HttpEntity<>(JSONObject.toJSONString(body), headers);

        String url = avataProperties.getAvataUrl() + NFT_CREATE_URL;
        try {
            // 接口调用
            ParameterizedTypeReference<Message<NFTOperateDTO>> typeReference = new ParameterizedTypeReference<Message<NFTOperateDTO>>() {
            };
            ResponseEntity<Message<NFTOperateDTO>> responseEntity = restTemplate.exchange(url, HttpMethod.POST, httpEntity, typeReference);

            Message<NFTOperateDTO> message = responseEntity.getBody();

            NFTOperateDTO nftOperateDTO = message.getData();
            // 成功
            log.info("创建NFT成功:" + nftOperateDTO);

            return nftOperateDTO;
        } catch (Exception e) {
            // 非200都会抛异常
            // 处理异常
            log.info("创建NFT失败"+nftCreateReq);
            e.printStackTrace();
            throw new RuntimeException("创建NFT失败");
        }
    }

    @Override
    public AccountListDTO queryaccount(AccountReq accountReq) {
        Map<String, Object> query = null == accountReq ? new HashMap<>() :
                JSON.parseObject(JSON.toJSONString(accountReq), new TypeReference<Map<String, Object>>() {
                });
        Long currentTime = System.currentTimeMillis();
        // 验签
        String signature = AvataUtils.signRequest(ACCOUNT_LIST_QUERY, query, null, currentTime, avataProperties.getApiSecret());

        UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(avataProperties.getAvataUrl() + ACCOUNT_LIST_QUERY );
        for (Map.Entry<String, Object> entry : query.entrySet()) {
            builder.queryParam(entry.getKey(), entry.getValue());
        }

        HttpHeaders headers = getHttpHeader(signature, currentTime);

        try {
            // 接口调用
            ParameterizedTypeReference<Message<AccountListDTO>> typeReference = new ParameterizedTypeReference<Message<AccountListDTO>>() {
            };
            ResponseEntity<Message<AccountListDTO>> responseEntity = restTemplate.exchange(new URI(builder.toUriString()), HttpMethod.GET, new HttpEntity<>(headers), typeReference);

            Message<AccountListDTO> message = responseEntity.getBody();
//            NFTClassListDTO nftClassListDTO = message.getData();
            AccountListDTO accountListDTO = message.getData();

            if (null != accountListDTO && null != accountListDTO.getAccounts() && accountListDTO.getAccounts().size() != 0) {
                // 遍历处理类别列表
                for (AccountDTO accountDTO: accountListDTO.getAccounts()) {

                }
            }

            log.info("NFT类别查询结果：" + accountListDTO);

            return accountListDTO;

        } catch (Exception e) {
            // 非200都会抛异常
            // 处理异常
            log.info("非200查询账户类别失败:"+accountReq);
            e.printStackTrace();
            throw new RuntimeException("查询账户类别失败");
        }
    }

    @Override
    public NFTOperateRecoderDTO queryRecords(NFTqueryrecordsReq nfTqueryrecordsReq,NFTDetailReq nftDetailReq) {
        Map<String, Object> query = null == nfTqueryrecordsReq ? new HashMap<>() :
                JSON.parseObject(JSON.toJSONString(nfTqueryrecordsReq), new TypeReference<Map<String, Object>>() {
                });
        Long currentTime = System.currentTimeMillis();
        // 验签
        String signature = AvataUtils.signRequest(NFT_QUERY_URL+nftDetailReq.getClass_id()+"/"+nftDetailReq.getNft_id()+"/"+"history", query, null, currentTime, avataProperties.getApiSecret());

        UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(avataProperties.getAvataUrl() +NFT_QUERY_URL+nftDetailReq.getClass_id()+"/"+nftDetailReq.getNft_id()+"/"+"history" );
        for (Map.Entry<String, Object> entry : query.entrySet()) {
            builder.queryParam(entry.getKey(), entry.getValue());
        }

        HttpHeaders headers = getHttpHeader(signature, currentTime);

        try {
            // 接口调用
            ParameterizedTypeReference<Message<NFTOperateRecoderDTO>> typeReference = new ParameterizedTypeReference<Message<NFTOperateRecoderDTO>>() {
            };
            ResponseEntity<Message<NFTOperateRecoderDTO>> responseEntity = restTemplate.exchange(new URI(builder.toUriString()), HttpMethod.GET, new HttpEntity<>(headers), typeReference);

            Message<NFTOperateRecoderDTO> message = responseEntity.getBody();
            NFTOperateRecoderDTO nftOperateRecoderDTO= message.getData();

            if (null != nftOperateRecoderDTO && null != nftOperateRecoderDTO.getOperation_records() && nftOperateRecoderDTO.getOperation_records().size() != 0) {
                // 遍历处理类别列表
                for (Operation operation:nftOperateRecoderDTO.getOperation_records()) {

                }
            }

            log.info("NFT类别查询结果：" + nftOperateRecoderDTO);

            return nftOperateRecoderDTO;

        } catch (Exception e) {
            // 非200都会抛异常
            // 处理异常
            log.info("非200查询NFT失败:"+nfTqueryrecordsReq);
            e.printStackTrace();
            throw new RuntimeException("查询NFT失败");
        }
    }

    @Override
    public NFTOperateDTO burnnft(NFTBurnReq nftBurnReq, NFTDetailReq nftDetailReq) {
        if (StringUtils.isBlank(nftDetailReq.getNft_id())) {
            throw new RuntimeException("缺少必传参数nftid");
        }
        if (StringUtils.isBlank(nftDetailReq.getClass_id())) {
            throw new RuntimeException("缺少必传参数CLassid");
        }
        if (StringUtils.isBlank(nftDetailReq.getOwner())) {
            throw new RuntimeException("缺少必传参数Owner");
        }
        if (StringUtils.isBlank(nftBurnReq.getOperation_id())) {
            throw new RuntimeException("缺少必传参数operationId");
        }
        Long currentTime  = System.currentTimeMillis();
        // 请求body
        Map<String, Object> body = new HashMap<>();
        body.put("operation_id", nftBurnReq.getOperation_id());
        // 验签
        String signature = AvataUtils.signRequest(NFT_PUBLISH_URL_PRE +nftDetailReq.getClass_id()+"/"+nftDetailReq.getOwner()+"/"+nftDetailReq.getNft_id(), null, body, currentTime, avataProperties.getApiSecret());
        // 请求体
        HttpHeaders headers = getHttpHeader(signature, currentTime);
        headers.setContentType(MediaType.parseMediaType("application/json"));

        HttpEntity<String> httpEntity = new HttpEntity<>(JSONObject.toJSONString(body), headers);

        String url = avataProperties.getAvataUrl() + NFT_PUBLISH_URL_PRE +nftDetailReq.getClass_id()+"/"+nftDetailReq.getOwner()+"/"+nftDetailReq.getNft_id();
        log.info("文昌链接口请求地址"+url);
        try {
            // 接口调用
            ParameterizedTypeReference<Message<NFTOperateDTO>> typeReference = new ParameterizedTypeReference<Message<NFTOperateDTO>>() {
            };
            ResponseEntity<Message<NFTOperateDTO>> responseEntity;
            responseEntity = restTemplate.exchange(url, HttpMethod.DELETE, httpEntity, typeReference);

            Message<NFTOperateDTO> message = responseEntity.getBody();

            NFTOperateDTO nftOperateDTO= message.getData();
            // 成功
            log.info("删除nft成功:" + nftOperateDTO);

            return nftOperateDTO;
        } catch (Exception e) {
            // 非200都会抛异常
            // 处理异常
            log.info("非200删除失败");
            e.printStackTrace();
            throw new RuntimeException("nft删除失败");
        }
    }

    HttpHeaders getHttpHeader(String signature, Long timestamp) {
        HttpHeaders headers = new HttpHeaders();
        headers.set("X-Api-Key", avataProperties.getApiKey());
        headers.set("X-Timestamp", timestamp.toString());
        headers.set("X-Signature", signature);

        return headers;
    }
}
